#ifndef NET_SETTINGS_H_
#define NET_SETTINGS_H_

#include "uarch/enums.h"
#include "uarch/types.h"


#ifndef SETTS
#define SETTS
typedef struct setts {
	char name[50];
	void *pointer;
} setts;
#endif

/**
 * Settings from the configuration file
 */
class Net_settings {
public:
	// Dynamic Parameters
    int                  num_nodes;
	int	                 mesh_x_dimension;
	int                  mesh_y_dimension;

    int                  num_nhoods;
    int                  nhood_x_blocking_factor;
    int                  nhood_y_blocking_factor;

    int                  num_mem_ctrls;
    int*                 mem_ctrl_array;

    unsigned int         heartrate;

	bool 				 net_infinite_bw;
	bool 				 sharer_forwarding;
	bool  				 wait_on_inv_acks;
	bool 				 livelock_check;
    bool                 processor_affinity;
    bool                 mem_model_enabled;
    bool                 regression_test;

    // SESC specific
	signed long long int sesc_rabbit;
	signed long long int sesc_nsim;
	signed long long int sesc_nsim_per_core;
    bool                 sesc_disable_llsc;

	long long int        warmup_time;
	long long int        warmup_time_per_core;

	// Cache Settings
	unsigned int		 cache_line_size_log2;
	unsigned int		 cache_line_size;

	// Processor
	bool                 LSQ_dependence;
    int                  mshrs_per_processor;
    int                  threads_per_processor;
    thread_map_t         thread_map_policy;

    // L1
    cache_type_t         l1_cache_type;
	int	                 l1_cache_size;
	int	   	             l1_cache_assoc;
	int                  l1_hit_time;
    int                  l1_mshrs;
	replacement_policy_t l1_replacement_policy;
	coherence_policy_t	 l1_coherence_policy;
	cache_policy_t		 l1_cache_policy;
	int                  l1_lookup_time;
    bool                 l1_infinite;

    // L2
    cache_type_t         l2_cache_type;
	int	                 l2_cache_size;
	int	   	             l2_cache_assoc;
	int                  l2_hit_time;
    int                  l2_mshrs;
	replacement_policy_t l2_replacement_policy;
	coherence_policy_t	 l2_coherence_policy;
	cache_policy_t		 l2_cache_policy;
	int                  l2_lookup_time;
    bool                 l2_infinite;

    // L3
    cache_type_t         l3_cache_type;
	int	                 l3_cache_size;
	int	   	             l3_cache_assoc;
	int                  l3_hit_time;
    int                  l3_mshrs;
	replacement_policy_t l3_replacement_policy;
	coherence_policy_t	 l3_coherence_policy;
	cache_policy_t		 l3_cache_policy;
	int                  l3_lookup_time;
    bool                 l3_infinite;

    // Directory
    int                  dir_tiers;
    int*                 dir_coherence_policy;
    dir_mode_t           dir_mode;
    int                  dir_addr_per_node_log2;

    // Cache index and home node swizzle
    paddr_t              cache_index_swizzle;
    paddr_t              dir_home_swizzle;

    // Set Dueling
    bool                 qsets_enabled;
    int                  qsets_interval;

    int                  remap_table_size;

    // Selective Replica Predictor
    predictor_t          sel_rep_pred;
    predictor_scope_t    sel_rep_pred_scope;
    bool                 train_on_loads;
    bool                 train_on_stores;
    int                  sel_rep_pred_threshold;

	// Network
	noc_topology_t       noc_topology;
    mesh_topology_t      mesh_topology;
    int					 express_link_len;
	bool				 express_link_active;
	// These are set by net_infinite_bandwidth and not the config file
	int					 num_virtual_channels;
	int					 buffer_entries_per_vc;

	long long int		 sampling_interval;

	sim_output_mode_t    report_output;

	paddr_t              debug_addr;
    paddr_t              test_addr;

    /* PCM / Memory Settings */
	unsigned int pcm_sets;
	unsigned int pcm_assoc;
	unsigned int dram_sets;
	unsigned int dram_assoc;
	unsigned int dram_line_sets;
	unsigned int dram_line_assoc;
	unsigned int pcm_lines;
	unsigned int mem_line_size;

	bool memory_baseline;

	int dram_hit_time;
	int pcm_rb_hit_time;
	int pcm_hit_time;
	int hdd_hit_time;

    Net_settings (void);
    ~Net_settings (void);

    void set_defaults (void);  
  	void get_settings (void);
    void get_topology (void);
    void print_settings (void);
};

#endif

